﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.InfoCardX509Validator
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace Microsoft.InfoCards
{
  internal class InfoCardX509Validator : X509CertificateValidator
  {
    private static InfoCardOfflineChainTrustValidator s_identityMachineChainTrustValidator = (InfoCardOfflineChainTrustValidator) null;
    private static InfoCardOfflineChainTrustValidator s_identityUserChainTrustValidator = (InfoCardOfflineChainTrustValidator) null;
    private static X509CertificateValidator s_identityPeerTrustValidator;
    private static X509Certificate2Collection m_supportingCertificates;

    static InfoCardX509Validator()
    {
      InfoCardX509Validator.s_identityMachineChainTrustValidator = new InfoCardOfflineChainTrustValidator(true);
      InfoCardX509Validator.s_identityUserChainTrustValidator = new InfoCardOfflineChainTrustValidator(false);
      InfoCardX509Validator.s_identityPeerTrustValidator = X509CertificateValidator.PeerTrust;
    }

    private InfoCardX509Validator(X509Certificate2Collection supportingCerts)
    {
      InfoCardX509Validator.m_supportingCertificates = supportingCerts;
    }

    public static X509CertificateValidator Create(
      X509Certificate2Collection supportingCerts)
    {
      return (X509CertificateValidator) new InfoCardX509Validator(supportingCerts);
    }

    public static void ValidateChainOrPeer(
      X509Certificate2 certificate,
      X509Certificate2Collection supportingRecipientCerts,
      out bool chainTrustPassed)
    {
      InfoCardX509Validator.Validate(certificate, supportingRecipientCerts, out chainTrustPassed);
    }

    public override void Validate(X509Certificate2 certificate)
    {
      bool chainTrustPassed;
      InfoCardX509Validator.Validate(certificate, InfoCardX509Validator.m_supportingCertificates, out chainTrustPassed);
    }

    public static bool ValidateChainOrPeerCallback(
      object sender,
      X509Certificate certificate,
      X509Chain chain,
      SslPolicyErrors sslPolicyErrors)
    {
      bool chainTrustPassed = false;
      if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None || (sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != SslPolicyErrors.None)
        return false;
      InfoCardTrace.Assert(certificate != null && null != chain, "We should have returned false for SslPolicyErrors.RemoteCertificateNotAvailable");
      try
      {
        InfoCardX509Validator.ValidateChainOrPeer(new X509Certificate2(certificate), chain.ChainPolicy.ExtraStore, out chainTrustPassed);
      }
      catch (SecurityTokenValidationException ex)
      {
        InfoCardTrace.TraceAndLogException((Exception) new IdentityValidationException(SR.GetString("RecipientCertificateNotValid"), (Exception) ex));
        return false;
      }
      return true;
    }

    private static void Validate(
      X509Certificate2 certificate,
      X509Certificate2Collection supportingRecipientCerts,
      out bool chainTrustPassed)
    {
      chainTrustPassed = false;
      string str = string.Empty;
      try
      {
        X509Chain chain;
        InfoCardX509Validator.ValidateChain(certificate, supportingRecipientCerts, out chain);
        chainTrustPassed = true;
      }
      catch (SecurityTokenValidationException ex)
      {
        str = ex.Message;
      }
      if (chainTrustPassed)
        return;
      try
      {
        InfoCardX509Validator.ValidatePeer(certificate);
      }
      catch (SecurityTokenValidationException ex)
      {
        throw InfoCardTrace.ThrowHelperError((Exception) new SecurityTokenValidationException(SR.GetString("X509ChainFailAndPeerTrustFail", (object) str, (object) ex.Message)));
      }
    }

    public static void ValidateChain(
      X509Certificate2 certificate,
      X509Certificate2Collection supportingCerts,
      out X509Chain chain)
    {
      try
      {
        InfoCardX509Validator.s_identityMachineChainTrustValidator.Validate(certificate, supportingCerts, out chain);
      }
      catch (SecurityTokenValidationException ex)
      {
        InfoCardX509Validator.s_identityUserChainTrustValidator.Validate(certificate, supportingCerts, out chain);
      }
    }

    public static bool TryValidateChain(
      X509Certificate2 certificate,
      X509Certificate2Collection supportingCerts)
    {
      bool flag = true;
      try
      {
        X509Chain chain;
        InfoCardX509Validator.ValidateChain(certificate, supportingCerts, out chain);
      }
      catch (SecurityTokenValidationException ex)
      {
        flag = false;
      }
      return flag;
    }

    public static void ValidatePeer(X509Certificate2 certificate)
    {
      InfoCardX509Validator.s_identityPeerTrustValidator.Validate(certificate);
    }
  }
}
